home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 July: Mac OS SDK / Dev.CD Jul 96 SDK / Dev.CD Jul 96 SDK1.toast / Development Kits (Disc 1) / OpenDoc Development Framework / ODFDev / Form / Sources / FormView.cpp < prev    next >
Encoding:
Text File  |  1996-04-25  |  25.3 KB  |  733 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                FormView.cpp
  4. //    Release Version:    $ ODF 1 $
  5. //
  6. //    Author:                Laurent Delamare
  7. //
  8. //    Copyright:            (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  9. //
  10. //========================================================================================
  11.  
  12. #include "Form.hpp"
  13.  
  14. #ifndef FORMVIEW_H
  15. #include "FormView.h"
  16. #endif
  17.  
  18. #ifndef PART_H
  19. #include "Part.h"
  20. #endif
  21.  
  22. #ifndef FRAME_H
  23. #include "Frame.h"
  24. #endif
  25.  
  26. #ifndef SCROLLED_H
  27. #include "ScrollEd.h"
  28. #endif
  29.  
  30. // ----- Framework Layer -----
  31.  
  32. #ifndef FWUTIL_H
  33. #include "FWUtil.h"
  34. #endif
  35.  
  36. #ifndef FWFRAME_H
  37. #include "FWFrame.h"
  38. #endif
  39.  
  40. #ifndef FWLISTBX_H
  41. #include "FWListBx.h"
  42. #endif
  43.  
  44. #ifndef FWBUTTON_H
  45. #include "FWButton.h"
  46. #endif
  47.  
  48. #ifndef FWEDVIEW_H
  49. #include "FWEdView.h"
  50. #endif
  51.  
  52. #ifndef FWPOPUP_H
  53. #include "FWPopup.h"
  54. #endif
  55.  
  56. #ifndef FWCLUSTR_H
  57. #include "FWClustr.h"
  58. #endif
  59.  
  60. #ifndef FWCONTXT_H
  61. #include "FWContxt.h"
  62. #endif
  63.  
  64. #ifndef FWSCLBAR_H
  65. #include "FWSclBar.h"
  66. #endif
  67.  
  68. #ifndef FWSTATIC_H
  69. #include "FWStatic.h"
  70. #endif
  71.  
  72. // ----- OS Layer -----
  73.  
  74. #ifndef FWMENU_H
  75. #include "FWMenu.h"
  76. #endif
  77.  
  78. #ifndef FWEVENT_H
  79. #include "FWEvent.h"
  80. #endif
  81.  
  82. #ifndef FWRECT_H
  83. #include "FWRect.h"
  84. #endif
  85.  
  86. #ifndef FWRECSHP_H
  87. #include "FWRecShp.h"
  88. #endif
  89.  
  90. #ifndef FWTXTSHP_H
  91. #include "FWTxtShp.h"
  92. #endif
  93.  
  94. #ifndef FWPICSHP_H
  95. #include "FWPicShp.h"        
  96. #endif
  97.  
  98. #ifndef FWALERT_H
  99. #include "FWAlert.h"            
  100. #endif
  101.  
  102. // ----- OpenDoc Includes -----
  103.  
  104. #ifndef SOM_Module_OpenDoc_Commands_defined
  105. #include <CmdDefs.xh>
  106. #endif
  107.  
  108. #ifndef SOM_Module_OpenDoc_StdProps_defined
  109. #include <StdProps.xh>
  110. #endif
  111.  
  112. #ifndef SOM_ODSession_xh
  113. #include <ODSessn.xh>
  114. #endif
  115.  
  116. #ifndef SOM_ODDispatcher_xh
  117. #include <Disptch.xh>
  118. #endif
  119.  
  120. //========================================================================================
  121. // RunTime Info
  122. //========================================================================================
  123.  
  124. #ifdef FW_BUILD_MAC
  125. #pragma segment odfform
  126. #endif
  127.  
  128. FW_DEFINE_CLASS_M1(CFormView, FW_CSuperView)
  129.  
  130. const FW_ClassTypeConstant LFormView = FW_TYPE_CONSTANT('F','r','m','v');
  131. FW_REGISTER_ARCHIVABLE_CLASS(LFormView, CFormView, CFormView::Create, FW_CView::Read, CFormView::Destroy, FW_CView::Write)
  132.  
  133. //========================================================================================
  134. // CFormView
  135. //========================================================================================
  136. // Implementation of a content view drawing a background picture
  137.  
  138. //----------------------------------------------------------------------------------------
  139. // CFormView::CFormView
  140. //----------------------------------------------------------------------------------------
  141.  
  142. CFormView::CFormView(Environment* ev, 
  143.                         FW_CSuperView* container,
  144.                         const FW_CRect& contentRect,
  145.                         const FW_CPoint& extent) :
  146.     FW_CSuperView(ev, container, contentRect, kFormViewID, extent, FW_kXYScrolling),
  147.     fFirstFormOn(true)
  148. {    
  149.     fRadioClusters[kModemSpeedCluster] = NULL;    
  150.     fRadioClusters[kDiscoverODFCluster] = NULL;    
  151.     fRadioClusters[kUsingOpenDocCluster] = NULL;    
  152.     
  153.     // Adjust the bounds but don't redraw now 
  154.     CenterInFrame(ev, contentRect.Size(), FALSE);
  155. }
  156.  
  157. //----------------------------------------------------------------------------------------
  158. // CFormView::CFormView
  159. //----------------------------------------------------------------------------------------
  160.  
  161. CFormView::CFormView(Environment* ev) :
  162.     FW_CSuperView(ev),
  163.     fFirstFormOn(true)
  164. {    
  165.     fRadioClusters[kModemSpeedCluster] = NULL;    
  166.     fRadioClusters[kDiscoverODFCluster] = NULL;    
  167.     fRadioClusters[kUsingOpenDocCluster] = NULL;    
  168.  
  169.     // Adjust the bounds but don't redraw now 
  170. //     CenterInFrame(ev, contentRect.Size(), FALSE);  can do that here?
  171. }
  172.  
  173. //----------------------------------------------------------------------------------------
  174. // CFormView::~CFormView
  175. //----------------------------------------------------------------------------------------
  176.  
  177. CFormView::~CFormView()
  178. {
  179.     // fRadioClusters are deleted when their last radio button is deleted
  180. }
  181.  
  182.  
  183. //----------------------------------------------------------------------------------------
  184. // CFormView::ActivateTarget
  185. //----------------------------------------------------------------------------------------
  186. // ActivateTarget is called the first time the frame gets the selection focus (because
  187. // a content view is always the frame's default target). We use this to change the target 
  188. // to be the first text-edit field, i.e. to activate this field for keyboard events.
  189.  
  190. void CFormView::ActivateTarget(Environment* ev, FW_Boolean tabSelection)
  191. {
  192.     FW_CView* edview = FindViewById(ev, kFirstNameEdViewID);
  193.     
  194.     // Be sure that the edit view wants to be the target before doing it
  195.     // (otherwise it would be activated even when it's invisible in the 2nd form)
  196.      
  197.     if (edview->WantsToBeTarget(ev))
  198.         edview->BecomeTarget(ev, tabSelection);
  199. }
  200.  
  201. //----------------------------------------------------------------------------------------
  202. //    CFormView::PostCreateViewFromStream
  203. //----------------------------------------------------------------------------------------
  204. // PostCreateViewFromStream is called after subviews are created from resources.  
  205. // Implement initializations for this view that can't be done from a stream.
  206.  
  207. void CFormView::PostCreateViewFromStream(Environment* ev)
  208. {
  209.     // ----- Link the frame to the list-box in order to respond to double-clicks
  210.     //        (standard controls are linked by defining their "receiver" resource field)
  211.     
  212.     // Note: this code could also reside in CFormFrame::PostCreateViewFromStream
  213.     //         if you prefer to do all PostCreate initializations in one place.
  214.     
  215.     CFormFrame* frame = (CFormFrame*)GetFrame(ev);
  216.     FW_CListBox* listbox = (FW_CListBox*)FindViewById(ev, kPlatformListBoxID);
  217.     
  218.     frame->AddNotifier(listbox, FW_kListBoxDoubleClickedMsg);
  219.     
  220.     // ----- Add a behavior to the list-box to handle mouse clicks
  221.     //        (easier than subclassing FW_CListBox and defining a new resource type)
  222.     
  223.     CMouseUpBehavior* behavior = FW_NEW(CMouseUpBehavior, (ev, listbox));
  224.     listbox->AdoptEventHandler(ev, behavior);
  225.     
  226.     // ----- Disable the "Remove" button by default
  227.     FW_CButton* rmButton = (FW_CButton*) FindViewById(ev, kRemoveButtonID);
  228.     rmButton->Disable(ev);
  229. }
  230.  
  231. //----------------------------------------------------------------------------------------
  232. // CFormView::CreateOwnSubViews
  233. //----------------------------------------------------------------------------------------
  234. // Called from CFormFrame::CreateSubViews if compiled without using view resources
  235.  
  236. void CFormView::CreateOwnSubViews(Environment* ev)
  237. {
  238.     // NOTE: we left this code commented out because of compiling problem in Release mode
  239.     //        with CodeWarrior 8.  Unless you have 60MB or so you'll get an "Out of memory"
  240.     //        error!  It must be caused by the full-optimization flags used in Release mode.
  241. #if 0
  242.     FW_Fixed fixed20     = FW_IntToFixed(20);
  243.     FW_Fixed fixed40     = FW_IntToFixed(40);
  244.     FW_CFont timesBold(FW_kTimes, FW_kBold, FW_IntToFixed(12));
  245.     FW_CFont helvetica(FW_kHelvetica, FW_kPlain, FW_IntToFixed(12));
  246.  
  247.     FW_CRect viewRect;        // working rect for creating the views
  248.  
  249.     // ----- Create edit fields in the content view
  250.     viewRect.Set(FW_IntToFixed(290), FW_IntToFixed(90), FW_IntToFixed(450), FW_IntToFixed(107));
  251.     FW_CPoint offset(FW_kFixed0, fixed20);
  252.     for (int i = 0; i < 4; i++) {
  253.         FW_CEditView* editView = FW_NEW(FW_CEditView, (ev, this, kFirstNameEdViewID+i, viewRect));
  254.         editView->SetFont(ev, timesBold);
  255.         viewRect += offset;
  256.     }
  257.     
  258.     // ----- Create custom scrolling edit view with its scrollbar
  259.     viewRect.Set(FW_IntToFixed(30), FW_IntToFixed(200), FW_IntToFixed(450), FW_IntToFixed(290));    
  260.     FW_CRect vertSbRect(viewRect.right - FW_kFixedPos1, viewRect.top, 
  261.                         viewRect.right + FW_IntToFixed(15), viewRect.bottom);
  262.     FW_CScrollBar* vertSB = FW_NEW(FW_CScrollBar, (ev, this, kEditVScrollBarID, vertSbRect));
  263.     vertSB->SetBindings(ev, FW_kFixedBounds);
  264.     CScrollEdit* scrollEdit = FW_NEW(CScrollEdit, (ev, this, kFirstNameEdViewID+4, viewRect, NULL, vertSB, FW_CString()));
  265.  
  266.     // ----- Create the "Subscribe" check box 
  267.     //         Use null message (no receiver) and initial value of 1 to turn it on
  268.     viewRect.Set(FW_IntToFixed(30), FW_IntToFixed(310), FW_IntToFixed(200), FW_IntToFixed(324));
  269.     FW_CButton* check = FW_NEW(FW_CButton, (ev, this, kSubscribeCheckID, viewRect, FW_kCheckButton, 
  270.                                 FW_CString("Subscribe to ODFFlash"), timesBold, 0, 1));
  271.  
  272.     // ----- Create the Modem Speed radio butttons, their group box & the radio cluster
  273.     viewRect.Set(FW_IntToFixed(30), FW_IntToFixed(360), FW_IntToFixed(220), FW_IntToFixed(440));
  274.     FW_CGroupBox* modemSpeed = FW_NEW(FW_CGroupBox, (ev, this, viewRect, 
  275.                                                 FW_CString(" Modem speed used"), timesBold));
  276.  
  277.     viewRect.Set(fixed40, FW_IntToFixed(380), FW_IntToFixed(210), FW_IntToFixed(396));
  278.     FW_CButton* radio1 = FW_NEW(FW_CButton, (ev, this, k14400RadioID, viewRect, 
  279.                                         FW_kRadioButton, FW_CString("14.4 Kbps or lower")));
  280.     viewRect.Offset(FW_kFixed0, fixed20);
  281.     FW_CButton* radio2 = FW_NEW(FW_CButton, (ev, this, k28800RadioID, viewRect, 
  282.                                         FW_kRadioButton, FW_CString("28.8 Kbps to 256 Kbps")));
  283.     viewRect.Offset(FW_kFixed0, fixed20);
  284.     FW_CButton* radio3 = FW_NEW(FW_CButton, (ev, this, kFasterRadioID, viewRect, 
  285.                                         FW_kRadioButton, FW_CString("Faster than 256 Kbps")));
  286.  
  287.     fRadioClusters[kModemSpeedCluster] = FW_NEW(FW_CRadioCluster, (ev));
  288.     fRadioClusters[kModemSpeedCluster]->AddRadio(ev, radio2);
  289.     fRadioClusters[kModemSpeedCluster]->AddRadio(ev, radio1);
  290.     fRadioClusters[kModemSpeedCluster]->AddRadio(ev, radio3);
  291.     
  292.     // ----- Create a list box (helvetica font, multiple selections, answer to double-clicks)
  293.     viewRect.Set(FW_IntToFixed(250), FW_IntToFixed(362), FW_IntToFixed(400), FW_IntToFixed(440));
  294.     FW_CListBox* listbox = FW_NEW(FW_CListBox, (ev, this, viewRect, kPlatformListBoxID, 10, 
  295.                                     true, helvetica, FW_kListBoxDoubleClickedMsg, false));
  296.     listbox->SetDrawingMode(ev, FALSE);
  297.     listbox->SetStringItem(ev, 1, FW_CString("Mac OS"));
  298.     listbox->SetStringItem(ev, 2, FW_CString("OS/2 Warp"));
  299.     listbox->SetStringItem(ev, 3, FW_CString("Windows 95"));
  300.     listbox->SetStringItem(ev, 4, FW_CString("Windows NT"));
  301.     listbox->SetStringItem(ev, 5, FW_CString("IBM AIX"));
  302.     listbox->SetStringItem(ev, 6, FW_CString("Sun Sparc Solaris"));
  303.     listbox->SetStringItem(ev, 7, FW_CString("Sun OS 4.1.x"));
  304.     listbox->SetStringItem(ev, 8, FW_CString("HP /UX"));
  305.     listbox->SetStringItem(ev, 9, FW_CString("Unix IRIX"));
  306.     listbox->SetStringItem(ev, 10, FW_CString("Unix Linux"));
  307.     listbox->SetDrawingMode(ev, TRUE);
  308.     
  309.     // ----- Create the Add/Remove buttons
  310.     viewRect.Set(FW_IntToFixed(410), FW_IntToFixed(370), FW_IntToFixed(480), FW_IntToFixed(390));
  311.     FW_CButton* addButton = FW_NEW(FW_CButton, (ev, this, kAddButtonID, viewRect, 
  312.                                         FW_kPushButton, FW_CString("Add")));
  313.     viewRect.Set(FW_IntToFixed(410), FW_IntToFixed(400), FW_IntToFixed(480), FW_IntToFixed(420));
  314.     FW_CButton* removeButton = FW_NEW(FW_CButton, (ev, this, kRemoveButtonID, viewRect, 
  315.                                         FW_kPushButton, FW_CString("Remove")));
  316.     removeButton->Disable(ev);
  317.     
  318.     // ----- Create the "browsing time" popup
  319.     viewRect.Set(FW_IntToFixed(30), FW_IntToFixed(477), FW_IntToFixed(230), FW_IntToFixed(497));
  320.     FW_CPopupMenu* popup1 = FW_NEW(FW_CPopupMenu, (ev, this, kBrowseTimePopupID, viewRect, 
  321.                                         kBrowseTimeMenuResID, FW_CString()));
  322.  
  323.     // ----- Create the "online time" popup
  324.     viewRect.Set(FW_IntToFixed(30), FW_IntToFixed(540), FW_IntToFixed(230), FW_IntToFixed(560));
  325.     FW_CPopupMenu* popup2 = FW_NEW(FW_CPopupMenu, (ev, this, kOnlineTimePopupID, viewRect, 
  326.                                         kOnlineTimeMenuResID, FW_CString()));
  327.  
  328.     // ----- Create the "First Discover" radio butttons & their radio cluster
  329.     viewRect.Set(FW_IntToFixed(30), FW_IntToFixed(580), FW_IntToFixed(350), FW_IntToFixed(700));
  330.     FW_CGroupBox* discoverGroupB = FW_NEW(FW_CGroupBox, (ev, this, viewRect, 
  331.                                         FW_CString(" How did you discover ODFWired?"), timesBold));
  332.  
  333.     viewRect.Set(fixed40, FW_IntToFixed(600), FW_IntToFixed(300), FW_IntToFixed(616));
  334.     FW_CButton* radio4 = FW_NEW(FW_CButton, (ev, this, kWorldMouthRadioID, viewRect, 
  335.                                         FW_kRadioButton, FW_CString("Word of mouth")));
  336.     viewRect.Offset(FW_kFixed0, fixed20);
  337.     FW_CButton* radio5 = FW_NEW(FW_CButton, (ev, this, kHyperLinkRadioID, viewRect, 
  338.                                         FW_kRadioButton, FW_CString("Hyperlink from another site:")));
  339.     viewRect.Offset(FW_kFixed0, fixed20);
  340.     FW_CButton* radio6 = FW_NEW(FW_CButton, (ev, this, kMacTechRadioID, viewRect, 
  341.                                         FW_kRadioButton, FW_CString("Ad in MacTech Magazine")));
  342.     viewRect.Offset(FW_kFixed0, fixed20);
  343.     FW_CButton* radio7 = FW_NEW(FW_CButton, (ev, this, kMagazineRadioID, viewRect, 
  344.                                         FW_kRadioButton, FW_CString("Other magazine, newspaper, radio")));
  345.     viewRect.Offset(FW_kFixed0, fixed20);
  346.     FW_CButton* radio8 = FW_NEW(FW_CButton, (ev, this, kOtherRadioID, viewRect, 
  347.                                         FW_kRadioButton, FW_CString("Other")));
  348.     fRadioClusters[kDiscoverODFCluster] = FW_NEW(FW_CRadioCluster, (ev));
  349.     fRadioClusters[kDiscoverODFCluster]->AddRadio(ev, radio4);
  350.     fRadioClusters[kDiscoverODFCluster]->AddRadio(ev, radio5);
  351.     fRadioClusters[kDiscoverODFCluster]->AddRadio(ev, radio6);
  352.     fRadioClusters[kDiscoverODFCluster]->AddRadio(ev, radio7);
  353.     fRadioClusters[kDiscoverODFCluster]->AddRadio(ev, radio8);
  354.     
  355.     // ----- Create the "using OpenDoc" radio butttons & their radio cluster
  356.     viewRect.Set(fixed40, FW_IntToFixed(725), FW_IntToFixed(100), FW_IntToFixed(740));
  357.     FW_CButton* radio9 = FW_NEW(FW_CButton, (ev, this, kYesRadioID, viewRect, 
  358.                                         FW_kRadioButton, FW_CString("Yes")));
  359.     viewRect.Offset(FW_kFixed0, fixed20);
  360.     FW_CButton* radio10 = FW_NEW(FW_CButton, (ev, this, kNoRadioID, viewRect, 
  361.                                         FW_kRadioButton, FW_CString("No")));
  362.     fRadioClusters[kUsingOpenDocCluster] = FW_NEW(FW_CRadioCluster, (ev));
  363.     fRadioClusters[kUsingOpenDocCluster]->AddRadio(ev, radio9);
  364.     fRadioClusters[kUsingOpenDocCluster]->AddRadio(ev, radio10);
  365.  
  366.     // ----- Create the "Subscribe" button at the bottom of the content view
  367.     FW_CString label("Join ODFWired!");
  368.     viewRect.Set(FW_IntToFixed(300), FW_IntToFixed(750), FW_IntToFixed(450), FW_IntToFixed(775));
  369.     FW_CButton* pushButton = FW_NEW(FW_CButton, (ev, this, kSubscribeButtonID, viewRect, 
  370.                                         FW_kPushButton, label));
  371.  
  372.     // ----- Link the frame to the controls it wants to respond to
  373.     //        (CFormFrame was defined as an FW_MReceiver and thus can respond to
  374.     //        notitications.  We could also have decided to make CFormView the
  375.     //        receiver, it's a matter of choice)
  376.     CFormFrame* frame = (CFormFrame*)GetFrame(ev);
  377.     
  378.     pushButton->LinkControlTo(ev, frame);
  379.     addButton->LinkControlTo(ev, frame);
  380.     removeButton->LinkControlTo(ev, frame);
  381.     radio10->LinkControlTo(ev, frame);
  382.     popup1->LinkControlTo(ev, frame);
  383.     
  384.     frame->AddNotifier(listbox, FW_kListBoxDoubleClickedMsg);
  385.  
  386.     // ----- Add a behavior to the list-box to handle mouse clicks
  387.     //        (easier than subclassing FW_CListBox and defining a new resource type)    
  388.     CMouseUpBehavior* behavior = FW_NEW(CMouseUpBehavior, (ev, listbox));
  389.     listbox->AdoptEventHandler(ev, behavior);
  390. #endif
  391. }
  392.  
  393. //----------------------------------------------------------------------------------------
  394. // CFormView::Draw
  395. //----------------------------------------------------------------------------------------
  396.  
  397. void CFormView::Draw(Environment *ev, ODFacet* odFacet, ODShape* invalidShape)
  398. {
  399.     // Set up drawing context for this view
  400.     FW_CViewContext vc(ev, this, odFacet, invalidShape);
  401.  
  402.     // Erase with white first 
  403.     FW_CRect invalidRect;
  404.     vc.GetClipRect(invalidRect);
  405.     FW_CRectShape::RenderRect(vc, invalidRect, FW_kFill, FW_kWhiteEraseInk);
  406.  
  407.     CFormFrame* frame = (CFormFrame*)GetFrame(ev);
  408.     
  409.     if (fFirstFormOn)
  410.     {
  411.         // Draw a background picture (which was loaded in CFormPrt::InitPicture)
  412.         // Note: this picture contains static text that could have been drawn using
  413.         //         Static Text view resources, as it was done in the 2nd form.
  414.         frame->GetFormPart()->GetPictShape1()->Render(vc);
  415.     }
  416.     else 
  417.     {
  418.         // Draw a background picture & the data entered by the user
  419.         frame->GetFormPart()->GetPictShape2()->Render(vc);
  420.         DrawUserData(ev, vc);
  421.     }
  422.     
  423.     // SubViews of CFormView are drawn recursively after this point.
  424.     
  425.     // Mac Note: If you want to draw Controls with a non-white background color to match
  426.     // the color of their parent view, you need either to define a color table for
  427.     // the window (see CPwdDialogFrame::FacetAdded for an example) or define color tables
  428.     // for individual controls.  See "Inside Macintosh: Macintosh Toolbox Essentials".
  429. }
  430.  
  431. //----------------------------------------------------------------------------------------
  432. // CFormView::CenterInFrame
  433. //----------------------------------------------------------------------------------------
  434.  
  435. void CFormView::CenterInFrame(Environment* ev, FW_CPoint& contentSize, FW_Boolean redraw)
  436. {
  437.     FW_CPoint    viewSize(GetSize(ev));
  438.     FW_CPoint    viewExtent(GetExtent(ev));
  439.     FW_CPoint    viewLoc;
  440.  
  441.     FW_CRect contentRect(FW_kZeroPoint, contentSize);
  442.     if (GetFrame(ev)->IsRoot(ev) == FALSE)
  443.     {
  444.         contentRect.Inset(FW_kFixedPos1);
  445.         contentSize = contentRect.Size();
  446.     }
  447.         
  448.     // Center the content view if it's smaller, or align it if it's bigger
  449.     if (contentSize.x > viewExtent.x) 
  450.     {
  451.         viewLoc.x = contentRect.left + FW_Half(contentSize.x - viewExtent.x);
  452.         viewSize.x = viewExtent.x;
  453.     }
  454.     else 
  455.     { 
  456.         viewLoc.x = contentRect.left;
  457.         viewSize.x = contentSize.x;
  458.     }
  459.     
  460.     if (contentSize.y > viewExtent.y) 
  461.     {
  462.         viewLoc.y = contentRect.top + FW_Half(contentSize.y - viewExtent.y);
  463.         viewSize.y = viewExtent.y;
  464.     }
  465.     else 
  466.     {
  467.         viewLoc.y = contentRect.top;
  468.         viewSize.y = contentSize.y;
  469.     }
  470.     
  471.     SetLocation(ev, viewLoc, redraw);
  472.     SetSize(ev, viewSize, redraw);
  473. }
  474.  
  475.  
  476. //----------------------------------------------------------------------------------------
  477. // CFormView::AdjustToNewLayout
  478. //----------------------------------------------------------------------------------------
  479.  
  480. void CFormView::AdjustToNewLayout(Environment *ev, const FW_CPoint& oldExtent, 
  481.                                     const FW_CPoint& newExtent, FW_Boolean redraw)    
  482. {
  483. FW_UNUSED(oldExtent);
  484.  
  485.     // Adjust the new frame size to remove scroll-bar space
  486.     FW_CPoint sbSize = FW_CScrollBar::GetDefaultScrollBarSize();
  487.     FW_CPoint size = newExtent;
  488.     size.x -= sbSize.x;
  489.     size.y -= sbSize.y;
  490.     
  491.     CenterInFrame(ev, size, redraw);
  492.     
  493.     return;
  494. }
  495.  
  496. //----------------------------------------------------------------------------------------
  497. // CFormView::DoMouseDown
  498. //----------------------------------------------------------------------------------------
  499.  
  500. FW_Boolean CFormView::DoMouseDown(Environment* ev, const FW_CMouseEvent& theMouseEvent)
  501. {
  502.     // Go back to the first form when clicking on the 2nd one
  503.     if (!fFirstFormOn)
  504.         SwitchForm(ev);
  505.  
  506.     return TRUE;
  507. }
  508.  
  509. //----------------------------------------------------------------------------------------
  510. // CFormView::SwitchForm
  511. //----------------------------------------------------------------------------------------
  512.  
  513. void     CFormView::SwitchForm(Environment* ev)
  514. {
  515.     if (fFirstFormOn)
  516.     {
  517.         fFirstFormOn = FALSE;
  518.         
  519.         // Hide all subviews but don't hide the form view itself
  520.         SetVisible(ev, FALSE, TRUE);
  521.         SetVisible(ev, TRUE, FALSE);
  522.     }
  523.     else
  524.     {
  525.         fFirstFormOn = TRUE;
  526.         
  527.         // Show all subviews
  528.         SetVisible(ev, TRUE, TRUE);
  529.         
  530.     }
  531.     
  532.     // Force a redraw
  533.     Invalidate(ev);
  534. }
  535.  
  536. //----------------------------------------------------------------------------------------
  537. // CFormView::DrawUserData
  538. //----------------------------------------------------------------------------------------
  539.  
  540. void CFormView::DrawUserData(Environment *ev, FW_CViewContext& vc)
  541. {
  542.     FW_CPoint        position;
  543.     FW_Fixed         vDelta = FW_IntToFixed(24);
  544.     int                i;
  545.     
  546.     FW_CString        str;
  547.     FW_CString32    yesStr("Yes");
  548.     FW_CString32    noStr("No");
  549.     
  550.     position.x = FW_IntToFixed(200);
  551.     position.y = FW_IntToFixed(90);
  552.  
  553.     // Edit views
  554.     FW_CEditView*    edview;
  555.     for (i = 0; i < 4; i++)
  556.     {
  557.         edview = (FW_CEditView*)FindViewById(ev, kFirstNameEdViewID+i);
  558.         str = edview->GetText(ev);
  559.         FW_CTextShape::RenderText(vc, str, position, FW_kNormalFont);
  560.         position.y += vDelta;
  561.     }
  562.     
  563.     // Check box
  564.     FW_CButton*        button;
  565.     button = (FW_CButton*)FindViewById(ev, kSubscribeCheckID);
  566.     FW_CTextShape::RenderText(vc, button->GetState(ev) ? yesStr : noStr, position, FW_kNormalFont);
  567.     position.y += vDelta;
  568.     
  569.     // Popups
  570.     FW_CPopupMenu* popup1 = (FW_CPopupMenu*) FindViewById(ev, kBrowseTimePopupID);
  571.     popup1->GetMenuString(ev, str);
  572.     FW_CTextShape::RenderText(vc, str, position, FW_kNormalFont);
  573.     position.y += vDelta;
  574.  
  575.     FW_CPopupMenu* popup2 = (FW_CPopupMenu*) FindViewById(ev, kOnlineTimePopupID);
  576.     popup2->GetMenuString(ev, str);
  577.     FW_CTextShape::RenderText(vc, str, position, FW_kNormalFont);
  578.     position.y += vDelta;
  579.     
  580.     // Radio buttons
  581.     CFormFrame*    frame = (CFormFrame*) GetFrame(ev);
  582.  
  583.     for (i = 0; i < kNumRadioClusters; i++)
  584.     {
  585.         button = fRadioClusters[i]->GetButtonOn(ev);
  586.         if (button) 
  587.         {
  588.             button->GetLabel(ev, str);
  589.             FW_CTextShape::RenderText(vc, str, position, FW_kNormalFont);
  590.             position.y += vDelta;
  591.         }
  592.     }
  593.     
  594.     // List box
  595.     FW_CListBox* list = (FW_CListBox*)FindViewById(ev, kPlatformListBoxID);
  596.     const short maxPlaforms = 10;
  597.     short platforms[maxPlaforms];
  598.     short numSelected = list->GetSelectedItems(ev, maxPlaforms, platforms);
  599.     if (numSelected > 0)
  600.     {
  601.         for (i = 0; i < numSelected; i++)
  602.         {
  603.             list->GetStringItem(ev, platforms[i], str);
  604.             FW_CTextShape::RenderText(vc, str, position, FW_kNormalFont);            
  605.             position.y += FW_IntToFixed(16);
  606.         }
  607.     }
  608.     
  609. }
  610.  
  611. //----------------------------------------------------------------------------------------
  612. // CFormView::ResetData
  613. //----------------------------------------------------------------------------------------
  614.  
  615. void CFormView::ResetData(Environment *ev)
  616. {
  617.     // Erase the text of the 5 edit views
  618.     FW_CEditView*    edview;
  619.     for (int i = 0; i < 4; i++)
  620.     {
  621.         edview = (FW_CEditView*)FindViewById(ev, kFirstNameEdViewID+i);
  622.         edview->SetText(ev, FW_CString());
  623.     }
  624.     
  625.     CScrollEdit* scrolledit = (CScrollEdit*)FindViewById(ev, kFirstNameEdViewID+4);
  626.     scrolledit->SetText(ev, FW_CString());
  627. }
  628.  
  629. //----------------------------------------------------------------------------------------
  630. //    CFormView::Create
  631. //----------------------------------------------------------------------------------------
  632.  
  633. void* CFormView::Create(FW_CReadableStream& stream, FW_ClassTypeConstant type)
  634. {
  635. FW_UNUSED(stream);
  636. FW_UNUSED(type);
  637.     FW_SOMEnvironment ev;
  638.     return new CFormView(ev);
  639. }
  640.  
  641. //----------------------------------------------------------------------------------------
  642. //    CFormView::Destroy
  643. //----------------------------------------------------------------------------------------
  644.  
  645. void CFormView::Destroy(void* object, FW_ClassTypeConstant type)
  646. {
  647. FW_UNUSED(type);
  648.     CFormView* self = (CFormView*) object;
  649.     delete self;
  650. }
  651.  
  652. //----------------------------------------------------------------------------------------
  653. //    CFormView::Flatten
  654. //----------------------------------------------------------------------------------------
  655.  
  656. void CFormView::Flatten(Environment* ev, FW_CWritableStream& archive) const
  657. {
  658.     FW_CSuperView::Flatten(ev, archive);
  659.     
  660.     // [LSD] to complete
  661. }
  662.  
  663. //----------------------------------------------------------------------------------------
  664. //    CFormView::InitializeFromStream
  665. //----------------------------------------------------------------------------------------
  666. // This method is required to handle the custom resource fields added to the base type
  667.  
  668. void CFormView::InitializeFromStream(Environment* ev, FW_CReadableStream& stream)
  669. {
  670.     // Read-in the base resource first
  671.     FW_CSuperView::InitializeFromStream(ev, stream);
  672.     
  673.     // Read-in the 3 radio-clusters defined in our RFormView type in "Views.fr"
  674.     // and initialize our radio-clusters array for future use.
  675.     for (int i = 0; i < kNumRadioClusters; i++) 
  676.     {
  677.         FW_READ_DYNAMIC_OBJECT(stream, &fRadioClusters[i], FW_CRadioCluster);
  678.     }    
  679. }
  680.  
  681.  
  682. //========================================================================================
  683. //    class CMouseUpBehavior
  684. //========================================================================================
  685. // Event handler class used to customize the mouse-click action in our list-box.
  686. // Having a behavior allows us to not have to subclass FW_CListBox (and also not to have
  687. // to define a new resource type in the .fr file)
  688.  
  689. FW_DEFINE_AUTO(CMouseUpBehavior)
  690.  
  691. //----------------------------------------------------------------------------------------
  692. //    CMouseUpBehavior::CMouseUpBehavior
  693. //----------------------------------------------------------------------------------------
  694.  
  695. CMouseUpBehavior::CMouseUpBehavior(Environment* ev, FW_CListBox* listBox) :
  696.     FW_MEventHandler(ev, NULL, kNoPriority),
  697.     fListBox(listBox)
  698. {
  699.     FW_END_CONSTRUCTOR
  700. }
  701.  
  702. //----------------------------------------------------------------------------------------
  703. //    CMouseUpBehavior::~CMouseUpBehavior
  704. //----------------------------------------------------------------------------------------
  705.  
  706. CMouseUpBehavior::~CMouseUpBehavior() 
  707. {
  708.     FW_START_DESTRUCTOR
  709. }
  710.  
  711. //----------------------------------------------------------------------------------------
  712. //    CMouseUpBehavior::DoMouseUp
  713. //----------------------------------------------------------------------------------------
  714. // We use the mouse up event to check if the listbox has 1 or more selected items
  715. // and enable the "Delete" button in that case.
  716. // (In that case we cannot use a mouse down event behavior because it would be executed
  717. //  before the listbox's mouse down handler, see FW_MEventHandler::DispatchMouseDown)
  718.  
  719. FW_Boolean CMouseUpBehavior::DoMouseUp(Environment* ev, const FW_CMouseEvent& theMouseEvent) 
  720. {
  721.     // Enable the "Delete" button if there are 1 or more selected items
  722.     if (fListBox->GetSelectedItem(ev) > 0)
  723.     {
  724.         FW_CSuperView* formView = fListBox->GetSuperView(ev);
  725.         FW_CButton* rmButton = (FW_CButton*) formView->FindViewById(ev, kRemoveButtonID);
  726.         FW_ASSERT(rmButton);
  727.         rmButton->Enable(ev);
  728.     }
  729.  
  730.     // let the list-box handle its mouse up event (although it doesn't matter here)
  731.     return FALSE;
  732. }
  733.